function varargout = VisualizeTimeFreq(varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Visualization HUB for timelock & frequency analysis data. % % Last modified: Feb.26, 2014 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Usage: % VisualizeTimeFreq(BuilderMatFile) % % Inputs: % BuilderMatFile = Can be empty or specify target Builder .mat file % Copyright (C) 2013-2014, Michael J. Cheung % % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more % details, see the documentation included with the software package. % % MEGPLS is free software: you can redistribute it and/or modify it under % the terms of the GNU General Public License version 2 as published by % the Free Software Foundation. This program is distributed in the hope % that it will be useful, but WITHOUT ANY WARRANTY; without even the % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % See the GNU General Public License for more details. % % You should have received a copy of the GNU General Public License along % with this program. If not, you can download the license here: % . % Last Modified by GUIDE v2.5 03-Mar-2014 15:16:15 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @VisualizeTimeFreq_OpeningFcn, ... 'gui_OutputFcn', @VisualizeTimeFreq_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT %--- Executes just before VisualizeTimeFreq is made visible. ---% %-------------------------------------------------------% function VisualizeTimeFreq_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to VisualizeTimeFreq (see VARARGIN) % Choose default command line output for VisualizeTimeFreq handles.output = hObject; % Make sure toolbox paths are added: [PipelineDir, ~, ~] = fileparts(which('VisualizeTimeFreq.m')); addpath(genpath(PipelineDir)); rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from AnalysisID rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox CheckToolboxPaths(PipelineDir); % Initialize variables and default settings: handles.name.GroupID = []; handles.name.SubjID = []; handles.name.CondID = []; handles.paths = []; handles.gui.FreqMethod = []; % To check if mtmfft (plotted differently). handles.gui.SubjIDAvgList = []; % SubjID list with GrpAvg at end of list. handles.gui.ManualChannelSelect = []; handles.gui.PlotOverlap = 'no'; % For legend construction handles.gui.PlotGrpAvg = 'no'; % Check for BuilderMat input: if isempty(varargin) handles.gui.BuilderMat = []; elseif numel(varargin) > 1 disp('Error: Input should be empty or a Builder .mat file.') error('Incorrect number of inputs.') elseif exist(varargin{1}, 'file') handles.gui.BuilderMat = varargin{1}; handles = LoadBuilderMat(handles, varargin{1}); end % Update handles structure guidata(hObject, handles); % UIWAIT makes VisualizeTimeFreq wait for user response (see UIRESUME) % uiwait(handles.figure1); %--- Outputs from this function are returned to the command line. ---% %--------------------------------------------------------------------% function varargout = VisualizeTimeFreq_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; %=====================================% % FUNCTIONS FOR LOADING BUILDER .MAT: % %=====================================% %--- Textbox to display selected path of Builder: ---% %----------------------------------------------------% function TextboxBuilderMat_Callback(hObject, eventdata, handles) EnteredText = get(handles.TextboxBuilderMat, 'String'); if ~isequal(EnteredText, handles.gui.BuilderMat) set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat); msgbox('Note: Use the button to change Builder .mat file.') end %--- Executes on button press in ButtonLoadBuilderMat. ---% %---------------------------------------------------------% function ButtonLoadBuilderMat_Callback(hObject, eventdata, handles) [BuilderFile, BuilderPath] = uigetfile('Builder_*.mat',... 'Select Builder .mat file to load:', 'MultiSelect', 'off'); if BuilderFile == 0 return; % If user cancels else handles.gui.BuilderMat = [BuilderPath,BuilderFile]; set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat); handles = LoadBuilderMat(handles, handles.gui.BuilderMat); guidata(hObject, handles); end %--- Loads variables from Builder .mat file. ---% %-----------------------------------------------% function OutputHandles = LoadBuilderMat(InputHandles, BuilderMat) handles = InputHandles; % Reset settings to default: handles.name.GroupID = []; handles.name.SubjID = []; handles.name.CondID = []; handles.paths = []; handles.gui.FreqMethod = []; % To check if mtmfft (plotted differently). handles.gui.SubjIDAvgList = []; % SubjID list with GrpAvg at end of list. handles.gui.ManualChannelSelect = []; handles.gui.PlotOverlap = 'no'; % For legend construction handles.gui.PlotGrpAvg = 'no'; % Load Builder .mat: LoadBuilder = load(BuilderMat); handles.name = LoadBuilder.name; handles.paths = LoadBuilder.paths; handles.gui.FreqMethod = LoadBuilder.gui.FreqMethod; % Update GUI: GroupIndex = get(handles.ListboxGroupID, 'Value'); set(handles.ListboxSubjID, 'Value', length(handles.name.SubjID{GroupIndex})+1); handles = UpdateNameIDs(handles); set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat); % Set output handles: OutputHandles = handles; %============================% % FUNCTIONS FOR ID DISPLAYS: % %============================% %--- Executes on selection change in ListboxGroupID. ---% %-------------------------------------------------------% function ListboxGroupID_Callback(hObject, eventdata, handles) handles = UpdateNameIDs(handles); guidata(hObject, handles); %--- Executes on selection change in ListboxSubjID. ---% %------------------------------------------------------% function ListboxSubjID_Callback(hObject, eventdata, handles) handles = UpdateNameIDs(handles); guidata(hObject, handles); %--- Executes on selection change in ListboxCondID. ---% %------------------------------------------------------% function ListboxCondID_Callback(hObject, eventdata, handles) handles = UpdateNameIDs(handles); guidata(hObject, handles); %--- Update GroupID's, SubjID's, and CondID's: ---% %-------------------------------------------------% function OutputHandles = UpdateNameIDs(InputHandles) handles = InputHandles; % Update GroupID listbox: set(handles.ListboxGroupID, 'String', handles.name.GroupID); GroupIndex = get(handles.ListboxGroupID, 'Value'); MaxGroupIndex = length(handles.name.GroupID); if isempty(GroupIndex) || GroupIndex == 0 || GroupIndex > MaxGroupIndex set(handles.ListboxGroupID, 'Value', MaxGroupIndex); end % Update SubjID listbox: if isempty(handles.name.SubjID) set(handles.ListboxSubjID, 'String', []); MaxSubjIndex = 0; else handles.gui.SubjIDAvgList{GroupIndex} = [handles.name.SubjID{GroupIndex}; 'GroupAvg']; set(handles.ListboxSubjID, 'String', handles.gui.SubjIDAvgList{GroupIndex}); MaxSubjIndex = length(handles.gui.SubjIDAvgList{GroupIndex}); end SubjIndices = get(handles.ListboxSubjID, 'Value'); if isempty(SubjIndices) || max(SubjIndices) == 0 || max(SubjIndices) > MaxSubjIndex set(handles.ListboxSubjID, 'Value', MaxSubjIndex); end % Update CondID listbox: set(handles.ListboxCondID, 'String', handles.name.CondID); CondIndices = get(handles.ListboxCondID, 'Value'); MaxCondIndex = length(handles.name.CondID); if isempty(CondIndices) || max(CondIndices) == 0 || max(CondIndices) > MaxCondIndex set(handles.ListboxCondID, 'Value', MaxCondIndex); end % Check SubjID & CondID multi-selection: % For frequency data (except for mtmfft), multiple datasets cannot be selected. if get(handles.ButtonViewFreqData, 'Value') == 1 && ... ~strcmp(handles.gui.FreqMethod, 'mtmfft') handles.gui.PlotOverlap = 'no'; if length(SubjIndices) > 1 set(handles.ListboxSubjID, 'Value', MaxSubjIndex); end if length(CondIndices) > 1 set(handles.ListboxCondID, 'Value', 1); end else if length(SubjIndices) == 1 && length(CondIndices) == 1 handles.gui.PlotOverlap = 'no'; elseif length(SubjIndices) > 1 && length(CondIndices) == 1 handles.gui.PlotOverlap = 'SubjIDs'; elseif length(SubjIndices) == 1 && length(CondIndices) > 1 handles.gui.PlotOverlap = 'CondIDs'; elseif length(SubjIndices) > 1 && length(CondIndices) > 1 handles.gui.PlotOverlap = 'Both'; end end % Check if GroupAvg is selected: if isempty(handles.gui.SubjIDAvgList) handles.gui.PlotGrpAvg = 'no'; else GroupIndex = get(handles.ListboxGroupID, 'Value'); GrpAvgIndex = length(handles.gui.SubjIDAvgList{GroupIndex}); if ismember(GrpAvgIndex, SubjIndices) handles.gui.PlotGrpAvg = 'yes'; else handles.gui.PlotGrpAvg = 'no'; end end % Set output handles: OutputHandles = handles; %======================================================% % FUNCTIONS FOR PLOTTING TIMELOCK / FREQUENCY RESULTS: % %======================================================% %--- Executes when selected object is changed in PanelPlotTimeFreq. ---% %----------------------------------------------------------------------% function PanelPlotTimeFreq_SelectionChangeFcn(hObject, eventdata, handles) % Enable multi-selection for timelock data: if get(handles.ButtonViewTimeData, 'Value') == 1 set(handles.ListboxSubjID, 'Max', 2); % Enable multi-selection set(handles.ListboxCondID, 'Max', 2); set(handles.ButtonViewGFP, 'Enable', 'on'); % Enable GFP button. end % For frequency methods except for mtmfft, disable multi-selection: if get(handles.ButtonViewFreqData, 'Value') == 1 if ~strcmp(handles.gui.FreqMethod, 'mtmfft') GroupIndex = get(handles.ListboxGroupID, 'Value'); SubjIndices = get(handles.ListboxSubjID, 'Value'); CondIndices = get(handles.ListboxCondID, 'Value'); if length(SubjIndices) > 1 set(handles.ListboxSubjID, 'Value', length(handles.gui.SubjIDAvgList{GroupIndex})); end if length(CondIndices) > 1 set(handles.ListboxCondID, 'Value', 1); end set(handles.ListboxSubjID, 'Max', 1); % Disable multi-selection set(handles.ListboxCondID, 'Max', 1); end set(handles.ButtonViewGFP, 'Enable', 'off'); % Disable GFP button. end % Update handles: handles = UpdateNameIDs(handles); guidata(hObject, handles); %--- Executes on button press in ButtonViewTimeData. function ButtonViewTimeData_Callback(hObject, eventdata, handles) %--- Executes on button press in ButtonViewFreqData. function ButtonViewFreqData_Callback(hObject, eventdata, handles) %--- Executes on button press in ButtonPlotSettings. ---% %-------------------------------------------------------% function ButtonPlotSettings_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Select Builder .mat file first.', 'Warning:'); return; end % Opens settings .m file: open([handles.paths.AnalysisID,'/SETTINGS/Settings_TimelockFreqPlot.m']); % --- Executes on button press in CheckboxInteractivePlots. function CheckboxInteractivePlots_Callback(hObject, eventdata, handles) %--- Acquires selected input time/freq data for plotting: ---% %------------------------------------------------------------% function [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(InputHandles) handles = InputHandles; paths = handles.paths; GroupIndex = get(handles.ListboxGroupID, 'Value'); SubjIndices = get(handles.ListboxSubjID, 'Value'); CondIndices = get(handles.ListboxCondID, 'Value'); DataIndex = 1; MissingFiles = {}; % Check to make sure multiselect is off for FreqAnalysis non-mtmfft data: if get(handles.ButtonViewFreqData, 'Value') == 1 if ~strcmp(handles.gui.FreqMethod, 'mtmfft') if length(SubjIndices) > 1 || length(CondIndices) > 1 TargetData = []; LegendData = []; LineStyles = []; ErrMsg = 'ERROR: Cannot select multiple datasets for TFR plot functions.'; return; end end end % Load GrpAvg file(s) to be plotted first: if strcmp(handles.gui.PlotGrpAvg, 'yes') for c = CondIndices if get(handles.ButtonViewTimeData, 'Value') == 1 TargetFile = paths.TimelockGrpAvg{GroupIndex}{c}; elseif get(handles.ButtonViewFreqData, 'Value') == 1 TargetFile = paths.FreqGrpAvg{GroupIndex}{c}; end CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq'); if CheckInput == 0 MissingFiles = [MissingFiles; TargetFile]; end TargetData{DataIndex} = TargetFile; LegendData{DataIndex} = ['GrpAvg_',handles.name.CondID{c}]; if length(SubjIndices) == 1 % If only GRPAVG selected LineStyles{DataIndex} = '-'; else LineStyles{DataIndex} = '.-'; end DataIndex = DataIndex + 1; end end % Compile input datasets: for s = SubjIndices for c = CondIndices if s == length(handles.gui.SubjIDAvgList{GroupIndex}) continue; % Skip GrpAvg index since already done above end if get(handles.ButtonViewTimeData, 'Value') == 1 TargetFile = paths.Timelock{GroupIndex}{s,c}; elseif get(handles.ButtonViewFreqData, 'Value') == 1 TargetFile = paths.Freq{GroupIndex}{s,c}; end CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq'); if CheckInput == 0 MissingFiles = [MissingFiles; TargetFile]; end TargetData{DataIndex} = TargetFile; switch handles.gui.PlotOverlap case {'no', 'Both'} LegendData{DataIndex} = ... [handles.name.SubjID{GroupIndex}{s},'_',handles.name.CondID{c}]; case 'SubjIDs' LegendData{DataIndex} = handles.name.SubjID{GroupIndex}{s}; case 'CondIDs' LegendData{DataIndex} = handles.name.CondID{c}; end if strcmp(handles.gui.PlotGrpAvg, 'yes') LineStyles{DataIndex} = '-'; % For now, keep non-grpavg lines solid else LineStyles{DataIndex} = '-'; end DataIndex = DataIndex + 1; end % Cond end % Subj if ~isempty(MissingFiles) ErrMsg = {'ERROR: Selected file(s) could not be found.'}; ErrMsg = [ErrMsg; MissingFiles]; else ErrMsg = []; end %--- Executes on button press in ButtonViewMultiplot. ---% %--------------------------------------------------------% function ButtonViewMultiplot_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Select Builder .mat file first.', 'Warning:'); return; end % Compile data to plot: [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(handles); if ~isempty(ErrMsg) msgbox(ErrMsg, 'Error:'); return; end InputChannels = GetInputChannels(handles); % Get plot settings: CurrentDir = pwd; cd([handles.paths.AnalysisID,'/SETTINGS/']); [cfgPlotER, cfgPlotTFR] = Settings_TimelockFreqPlot(LineStyles); cd(CurrentDir); if get(handles.CheckboxInteractivePlots, 'Value') == 1 cfgPlotER.interactive = 'yes'; cfgPlotTFR.interactive = 'yes'; else cfgPlotER.interactive = 'no'; cfgPlotTFR.interactive = 'no'; end % Plot data: figure; if get(handles.ButtonViewTimeData, 'Value') == 1 cfgPlotER.legend = LegendData; cfgPlotER.channel = InputChannels; cfgPlotER.inputfile = TargetData; ft_multiplotER(cfgPlotER); elseif get(handles.ButtonViewFreqData, 'Value') == 1 if strcmp(handles.gui.FreqMethod, 'mtmfft') cfgPlotER.legend = LegendData; cfgPlotER.channel = InputChannels; cfgPlotER.inputfile = TargetData; ft_multiplotER(cfgPlotER); else cfgPlotTFR.channel = InputChannels; cfgPlotTFR.inputfile = TargetData{1}; ft_multiplotTFR(cfgPlotTFR); end end %--- Executes on button press in ButtonViewSingleplot. ---% %---------------------------------------------------------% function ButtonViewSingleplot_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Select Builder .mat file first.', 'Warning:'); return; end % Compile data to plot: [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(handles); if ~isempty(ErrMsg) msgbox(ErrMsg, 'Error:'); return; end InputChannels = GetInputChannels(handles); % Get plot settings: CurrentDir = pwd; cd([handles.paths.AnalysisID,'/SETTINGS/']); [cfgPlotER, cfgPlotTFR] = Settings_TimelockFreqPlot(LineStyles); cd(CurrentDir); if get(handles.CheckboxInteractivePlots, 'Value') == 1 cfgPlotER.interactive = 'yes'; cfgPlotTFR.interactive = 'yes'; else cfgPlotER.interactive = 'no'; cfgPlotTFR.interactive = 'no'; end % Plot data: figure; if get(handles.ButtonViewTimeData, 'Value') == 1 cfgPlotER.legend = LegendData; cfgPlotER.channel = InputChannels; cfgPlotER.inputfile = TargetData; ft_singleplotER(cfgPlotER); elseif get(handles.ButtonViewFreqData, 'Value') == 1 if strcmp(handles.gui.FreqMethod, 'mtmfft') cfgPlotER.legend = LegendData; cfgPlotER.channel = InputChannels; cfgPlotER.inputfile = TargetData; ft_singleplotER(cfgPlotER); else % For ft_singleplotTFR, you need to load dataset (no cfg.inputfile option): InputData = []; InputData = LoadFTmat(TargetData{1}, 'ViewTimeFreq'); cfgPlotTFR.channel = InputChannels; ft_singleplotTFR(cfgPlotTFR, InputData); end end %--- Acquires selected GFP data for plotting: ---% %------------------------------------------------% function [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetGFPData(InputHandles) handles = InputHandles; paths = handles.paths; GroupIndex = get(handles.ListboxGroupID, 'Value'); SubjIndices = get(handles.ListboxSubjID, 'Value'); CondIndices = get(handles.ListboxCondID, 'Value'); DataIndex = 1; MissingFiles = {}; % Check to make sure you are viewing timelock data:: if get(handles.ButtonViewFreqData, 'Value') == 1 TargetData = []; LegendData = []; LineStyles = []; ErrMsg = 'ERROR: Switch viewer to time-domain & ERP data to view GFP results.'; return; end % Load GrpAvg file(s) to be plotted first: if strcmp(handles.gui.PlotGrpAvg, 'yes') for c = CondIndices TargetFile = paths.GlobalMeanFieldGrpAvg{GroupIndex}{c}; CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq'); if CheckInput == 0 MissingFiles = [MissingFiles; TargetFile]; end TargetData{DataIndex} = TargetFile; LegendData{DataIndex} = ['GrpAvg_',handles.name.CondID{c}]; if length(SubjIndices) == 1 % If only GRPAVG selected LineStyles{DataIndex} = '-'; else LineStyles{DataIndex} = '.-'; end DataIndex = DataIndex + 1; end end % Compile input datasets: for s = SubjIndices for c = CondIndices if s == length(handles.gui.SubjIDAvgList{GroupIndex}) continue; % Skip GrpAvg index since already done above end TargetFile = paths.GlobalMeanField{GroupIndex}{s,c}; CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq'); if CheckInput == 0 MissingFiles = [MissingFiles; TargetFile]; end TargetData{DataIndex} = TargetFile; switch handles.gui.PlotOverlap case {'no', 'Both'} LegendData{DataIndex} = ... [handles.name.SubjID{GroupIndex}{s},'_',handles.name.CondID{c}]; case 'SubjIDs' LegendData{DataIndex} = handles.name.SubjID{GroupIndex}{s}; case 'CondIDs' LegendData{DataIndex} = handles.name.CondID{c}; end if strcmp(handles.gui.PlotGrpAvg, 'yes') LineStyles{DataIndex} = '-'; % For now, keep non-grpavg lines solid else LineStyles{DataIndex} = '-'; end DataIndex = DataIndex + 1; end % Cond end % Subj if ~isempty(MissingFiles) ErrMsg = {'ERROR: Selected file(s) could not be found.'}; ErrMsg = [ErrMsg; MissingFiles]; else ErrMsg = []; end %--- Executes on button press in ButtonViewGFP. ---% %-------------------------------------------------------% function ButtonViewGFP_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Select Builder .mat file first.', 'Warning:'); return; end % Compile GFP data to plot: [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetGFPData(handles); if ~isempty(ErrMsg) msgbox(ErrMsg, 'Error:'); return; end % Get plot settings: CurrentDir = pwd; cd([handles.paths.AnalysisID,'/SETTINGS/']); [cfgPlotER, ~] = Settings_TimelockFreqPlot(LineStyles); cd(CurrentDir); % Remove fields from cfgPlotER that don't apply: cfgPlotER = rmfield(cfgPlotER, 'channel'); cfgPlotER = rmfield(cfgPlotER, 'baseline'); cfgPlotER = rmfield(cfgPlotER, 'baselinetype'); cfgPlotER = rmfield(cfgPlotER, 'layout'); cfgPlotER = rmfield(cfgPlotER, 'maskstyle'); % Plot data: figure; cfgPlotER.legend = LegendData; cfgPlotER.inputfile = TargetData; cfgPlotER.interactive = 'no'; % Force off, doesn't apply here. ft_singleplotER(cfgPlotER); %--- Executes on button press in ButtonCloseAll. ---% %---------------------------------------------------% function ButtonCloseAll_Callback(hObject, eventdata, handles) figs = get(0,'children'); figs(figs == gcf) = []; % close all except GUI. close(figs) %==================================% % FUNCTIONS FOR CHANNEL SELECTION: % %==================================% %--- Executes when selected object is changed in PanelChannelSelect. ---% %-----------------------------------------------------------------------% function PanelChannelSelect_SelectionChangeFcn(hObject, eventdata, handles) handles = UpdateChannelSettings(handles); guidata(hObject, handles); % --- Executes on button press in ButtonAllChannels. function ButtonAllChannels_Callback(hObject, eventdata, handles) % --- Executes on button press in ButtonManualChannelSelect. function ButtonManualChannelSelect_Callback(hObject, eventdata, handles) %--- Compiles input channels for plotting: ---% %---------------------------------------------% function InputChannels = GetInputChannels(InputHandles) handles = InputHandles; if get(handles.ButtonAllChannels, 'Value') == 1 InputChannels = 'MEG'; return; end InputChannels = {}; % Left channel groups: if get(handles.CheckboxMLF, 'Value') == 1 InputChannels = [InputChannels; 'MLF']; end if get(handles.CheckboxMLC, 'Value') == 1 InputChannels = [InputChannels; 'MLC']; end if get(handles.CheckboxMLO, 'Value') == 1 InputChannels = [InputChannels; 'MLO']; end if get(handles.CheckboxMLP, 'Value') == 1 InputChannels = [InputChannels; 'MLP']; end if get(handles.CheckboxMLT, 'Value') == 1 InputChannels = [InputChannels; 'MLT']; end % Right channel groups: if get(handles.CheckboxMRF, 'Value') == 1 InputChannels = [InputChannels; 'MRF']; end if get(handles.CheckboxMRC, 'Value') == 1 InputChannels = [InputChannels; 'MRC']; end if get(handles.CheckboxMRO, 'Value') == 1 InputChannels = [InputChannels; 'MRO']; end if get(handles.CheckboxMRP, 'Value') == 1 InputChannels = [InputChannels; 'MRP']; end if get(handles.CheckboxMRT, 'Value') == 1 InputChannels = [InputChannels; 'MRT']; end % Zenith channel groups: if get(handles.CheckboxMZF, 'Value') == 1 InputChannels = [InputChannels; 'MZF']; end if get(handles.CheckboxMZC, 'Value') == 1 InputChannels = [InputChannels; 'MZC']; end if get(handles.CheckboxMZO, 'Value') == 1 InputChannels = [InputChannels; 'MZO']; end if get(handles.CheckboxMZP, 'Value') == 1 InputChannels = [InputChannels; 'MZP']; end if get(handles.CheckboxMZT, 'Value') == 1 InputChannels = [InputChannels; 'MZT']; end % Manually selected channels: if ~isempty(handles.gui.ManualChannelSelect) InputChannels = [InputChannels; handles.gui.ManualChannelSelect]; end % --- Executes on button press in CheckboxMLF. function CheckboxMLF_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMLC. function CheckboxMLC_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMLO. function CheckboxMLO_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMLP. function CheckboxMLP_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMLT. function CheckboxMLT_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMRF. function CheckboxMRF_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMRC. function CheckboxMRC_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMRO. function CheckboxMRO_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMRP. function CheckboxMRP_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMRT. function CheckboxMRT_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMZF. function CheckboxMZF_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMZC. function CheckboxMZC_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMZO. function CheckboxMZO_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMZP. function CheckboxMZP_Callback(hObject, eventdata, handles) % --- Executes on button press in CheckboxMZT. function CheckboxMZT_Callback(hObject, eventdata, handles) % --- Executes on selection change in ListboxAddedChannels. function ListboxAddedChannels_Callback(hObject, eventdata, handles) %--- Executes on button press in ButtonManualAdd. ---% %----------------------------------------------------% function ButtonManualAdd_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Please select Builder .mat file first.', 'Warning:'); return; end % Get channel data from first dataset: if exist(handles.paths.MEGdata{1}{1,1}, 'file') MEGdata = LoadFTmat(handles.paths.MEGdata{1}{1,1}, 'ViewTimeFreq'); ChannelList = MEGdata.label; else msgbox('Error: Failed to acquire channel data (from first dataset).', 'Error:'); return; end if ~isempty(handles.gui.ManualChannelSelect) ChannelList(find(ismember(ChannelList, handles.gui.ManualChannelSelect))) = []; end % Open listbox for channel selection: SelectedIndices = listdlg('PromptString', 'Manually select channels to view:', ... 'SelectionMode', 'multiple', 'ListString', ChannelList); if isempty(SelectedIndices) return; % If user cancels end SelectedChannels = ChannelList(SelectedIndices); handles.gui.ManualChannelSelect = [handles.gui.ManualChannelSelect; SelectedChannels]; % Update handles: handles = UpdateChannelSettings(handles); guidata(hObject, handles); %--- Executes on button press in ButtonManualRemove. ---% %-------------------------------------------------------% function ButtonManualRemove_Callback(hObject, eventdata, handles) if isempty(handles.gui.BuilderMat) msgbox('Warning: Please select Builder .mat file first.', 'Warning:'); return; end % Remove selected channels: SelectedIndices = get(handles.ListboxAddedChannels, 'Value'); handles.gui.ManualChannelSelect(SelectedIndices) = []; % Update handles: handles = UpdateChannelSettings(handles); guidata(hObject, handles); %--- Updates channel selection settings: ---% %-------------------------------------------% function OutputHandles = UpdateChannelSettings(InputHandles) handles = InputHandles; % Update listboxes: set(handles.ListboxAddedChannels, 'String', handles.gui.ManualChannelSelect); SelectedIndices = get(handles.ListboxAddedChannels, 'Value'); MaxIndex = length(handles.gui.ManualChannelSelect); if isempty(SelectedIndices) || max(SelectedIndices) == 0 || max(SelectedIndices) > MaxIndex set(handles.ListboxAddedChannels, 'Value', MaxIndex); end % Enable/Disable GUI components: if get(handles.ButtonAllChannels, 'Value') == 1 set(findall(handles.PanelChannelGroups, '-property', 'Enable'), 'Enable', 'off'); set(handles.ListboxAddedChannels, 'Enable', 'off'); set(handles.ButtonManualAdd, 'Enable', 'off'); set(handles.ButtonManualRemove, 'Enable', 'off'); elseif get(handles.ButtonManualChannelSelect, 'Value') == 1 set(findall(handles.PanelChannelGroups, '-property', 'Enable'), 'Enable', 'on'); set(handles.ListboxAddedChannels, 'Enable', 'on'); set(handles.ButtonManualAdd, 'Enable', 'on'); set(handles.ButtonManualRemove, 'Enable', 'on'); end % Set output handles: OutputHandles = handles; %==============================% % GUIDE "CREATEFCN" FUNCTIONS: % %==============================% % --- Executes during object creation, after setting all properties. function TextboxBuilderMat_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxGroupID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxSubjID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxCondID_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes during object creation, after setting all properties. function ListboxAddedChannels_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end